<html>
<head><meta charset="utf-8"><title>Making sense of LTO modes in rustc · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html">Making sense of LTO modes in rustc</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="235196034"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235196034" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235196034">(Apr 19 2021 at 15:04)</a>:</h4>
<p>Hi there!</p>
<p>I'm trying to figure out the implications of all of the different LTO modes that rust supports. I've been prodding around in the source, but I feel none wiser.</p>
<p>So we have:</p>
<div class="codehilite"><pre><span></span><code>  pub enum Lto {
      /// Don&#39;t do any LTO whatsoever
      No,

      /// Do a full crate graph LTO with ThinLTO
      Thin,

      /// Do a local graph LTO with ThinLTO (only relevant for multiple codegen
      /// units).
      ThinLocal,

      /// Do a full crate graph LTO with &quot;fat&quot; LTO
      Fat,
  }
</code></pre></div>
<p>I know that one of these modes is where a linker plugin is used. Is that  <code>fat</code>? Or can any of the (non-off) options use a linker plugin?</p>
<p>I'm also confused as to what "full crate" and "local" mean in this context?</p>
<ul>
<li>Does "full crate" mean "one whole crate" or "all crates"?</li>
<li>Is "Local" meaning "local to a codegen unit", or "local to a crate"?</li>
</ul>
<p>I'm happy to raise a PR to improve the comments if others think this would be worthwhile too.</p>
<p>Context: I would like to embed post-lto llvm bitcode into binary outputs. It looks like the liblto plugin <a href="https://reviews.llvm.org/rGc8e0bb3b2c24ef59556d81a275fb1f5db64899d3">can do this</a> but it's not clear if and when I could use this from rustc, or if using a plugin is the only way to get what I'd like.</p>
<p>Ideally I'd be able to get this without changes to rustc, but that may not be possible.</p>
<p>Thanks.</p>



<a name="235196590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235196590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235196590">(Apr 19 2021 at 15:06)</a>:</h4>
<p><code>ThinLocal</code> applies thin lto on the crate that is currently being compiled and then emits regular object files. This allows for inlining of functions between codegen units within the same crate without having to do all LTO just before linking. <code>ThinLocal</code> is the default in release mode when lto is neither explicitly enabled, nor disabled.</p>



<a name="235196843"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235196843" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235196843">(Apr 19 2021 at 15:07)</a>:</h4>
<p>None of these options use a linker plugin. LTO is handled solely by rustc. You can enable linker plugin LTO with <code>-Clinker-plugin-lto</code> instead.</p>



<a name="235196870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235196870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235196870">(Apr 19 2021 at 15:07)</a>:</h4>
<p><span class="user-mention" data-user-id="223288">@Edd Barrett</span></p>



<a name="235200761"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235200761" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235200761">(Apr 19 2021 at 15:30)</a>:</h4>
<p>Hi Bjorn!</p>
<blockquote>
<p>None of these options use a linker plugin. LTO is handled solely by rustc.</p>
</blockquote>
<p>OK, that clears that aspect up.</p>
<blockquote>
<p>ThinLocal applies thin lto on the crate that is currently being compiled and then emits regular object files.</p>
</blockquote>
<p>OK, so I take "local graph" to mean "intra-crate graph", which means that "full crate graph" means "inter-crate graph".</p>
<p>Then from reading <a href="https://www.reddit.com/r/rust/comments/ijwya5/whats_the_deal_with_lto/g3hkm4p/?utm_source=reddit&amp;utm_medium=web2x&amp;context=3">this</a> I take the difference between "Thin" and "Fat" to be "Fat" just inlines more aggressively. Is that right?</p>



<a name="235203979"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235203979" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235203979">(Apr 19 2021 at 15:51)</a>:</h4>
<p>I wouldn't characterize "thin" vs "fat" as being more or less aggressive.  Sometimes thin can generate better code.  I think <a href="http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html">http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html</a> is a pretty good explanation of what it does.</p>



<a name="235205180"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235205180" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235205180">(Apr 19 2021 at 15:59)</a>:</h4>
<p>I'm not sure if you've seen the documentation for <a href="https://doc.rust-lang.org/nightly/rustc/codegen-options/index.html#lto">lto</a> and <a href="https://doc.rust-lang.org/nightly/rustc/codegen-options/index.html#linker-plugin-lto">linker-plugin-lto</a> which has its own <a href="https://doc.rust-lang.org/nightly/rustc/linker-plugin-lto.html">chapter</a>.</p>



<a name="235213104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235213104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235213104">(Apr 19 2021 at 16:51)</a>:</h4>
<p>Ah, I had missed these docs. Thank you!</p>



<a name="235214587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235214587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235214587">(Apr 19 2021 at 17:02)</a>:</h4>
<p>OK, those docs make it really clear.</p>
<p>My only remaining question is: if I defer LTO to the linker, can one still choose thin/fat LTO, or is that implicitly a fat LTO at that point?</p>
<p>(I'm trying to figure out at which layer I should implement embedding the post-lto bitcode)</p>



<a name="235214786"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235214786" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235214786">(Apr 19 2021 at 17:03)</a>:</h4>
<p>Local thin lto is impossible with linker plugin lto by default. I would expect that the linker plugin does support regular thin lto though.</p>



<a name="235214908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235214908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235214908">(Apr 19 2021 at 17:04)</a>:</h4>
<p>Linker plugin lto is the only option for C/C++ as far as I know and thin lto is not a rust invention.</p>



<a name="235314356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235314356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235314356">(Apr 20 2021 at 09:30)</a>:</h4>
<p>I've raised <a href="https://github.com/rust-lang/rust/pull/84365">this PR</a> in an attempt to improve the docstrings of the <code>Lto</code> struct. Let me know what you think.</p>



<a name="235349811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Making%20sense%20of%20LTO%20modes%20in%20rustc/near/235349811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edd Barrett <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Making.20sense.20of.20LTO.20modes.20in.20rustc.html#235349811">(Apr 20 2021 at 14:10)</a>:</h4>
<p>Well, I managed to get a LTO linker plugin working, although it wasn't as easy as I'd hoped:<br>
<a href="https://github.com/rust-lang/rust/issues/60059#issuecomment-823302769">https://github.com/rust-lang/rust/issues/60059#issuecomment-823302769</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>